package com.ek.common.task;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ek.common.FutureResponse;
import com.ek.common.MessageSender;
import com.ek.common.RoutingTable;
import com.ek.kademlia.protocol.Response;
import com.ek.kademlia.protocol.impl.DiscoveryMessage;
import com.ek.service.TaskManager;
import com.ek.service.mina.ComunicationService;

public class Discovery extends FutureTask<Boolean> {
    private static final transient Logger log = LoggerFactory.getLogger(Discovery.class);

    public Discovery(final byte[] nodeID, final SocketAddress socketAddress, final MessageSender sender, final TaskManager taskManager, final RoutingTable routingTable) {
        super(new Callable<Boolean>() {

            public Boolean call() throws Exception {
                log.debug("call");
                DiscoveryMessage message = new DiscoveryMessage();
                message.setMessageID(UUID.randomUUID().toString().getBytes());
                message.setNodeID(nodeID);
                log.debug("sending discovery message ...");
                InetSocketAddress address = (InetSocketAddress) socketAddress;
                FutureResponse<Response> sended = sender.sendMessage(message, new InetSocketAddress(address.getAddress(), ComunicationService.PORT));
                log.debug("sended, waiting for response...");
                Response response = sended.get(3, TimeUnit.SECONDS);
                if (response != null) {
                    log.debug("response received.");
                    taskManager.put(new AddContact(response.getSocketAddress(), response, routingTable));
                    return true;
                } else {
                    log.debug("response not received.");
                    return false;
                }
            }
        });
    }
}
